home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / pccp019.zip / XMCRC1KR.C < prev    next >
Text File  |  1992-05-04  |  7KB  |  404 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC: >qcl term.c graphics.lib
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<sys\types.h>
  10. #include<sys\stat.h>
  11. #include<signal.h>
  12.  
  13. #define DLLSBREG 0
  14. #define DLMSBREG 1
  15. #define INTCTLREG 1
  16. #define INTIDREG 2
  17. #define LCTLREG 3
  18. #define MCTLREG 4
  19. #define STATREG 5
  20. #define MSTATREG 6
  21.  
  22. #define CTSMASK 0x10
  23. #define TXMTMASK 0x20
  24. #define RXRDYMASK 0x01
  25.  
  26. #define INTACK 0x20
  27.  
  28. #define DB7 0x02
  29. #define DB8 0x03
  30. #define STOP2 0x04
  31. #define PARITYEN 0x08
  32. #define PARITYEVEN 0x10
  33. #define DLAB 0x80
  34.  
  35. #define INTBASE1 0x20
  36. #define INTMASK1 0x21
  37. #define INTBASE2 0xa0
  38. #define INTMASK2 0xa1
  39.  
  40. #define TBUFSIZ 2048
  41.  
  42. #define NAK 21
  43. #define ACK 6
  44. #define SOH 1
  45. #define STX 2
  46. #define EOT 4
  47. #define CAN 24
  48.  
  49. int index, basereg;
  50. unsigned char buf[TBUFSIZ];
  51. unsigned char diffintmask, irqnum;
  52. void (interrupt far *oldvect)();
  53.  
  54. void interrupt far inthndl(_es, _ds, _di, _si, _bp, _sp,
  55.               _bx, _dx, _cx, _ax, _ip, _cs, _flags)
  56.     unsigned _es, _ds, _di, _si, _bp, _sp;
  57.     unsigned _bx, _dx, _cx, _ax, _ip, _cs, _flags;
  58.     {
  59.     if(inp(basereg+STATREG)&RXRDYMASK)
  60.         {
  61.         buf[index++]=inp(basereg)&0xff;
  62.         index=index%TBUFSIZ;
  63.         }
  64.     outp(INTBASE1, INTACK);
  65.     outp(INTBASE2, INTACK);
  66.     }
  67.  
  68. sendchar(c)
  69.     unsigned char c;
  70.     {
  71.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)));
  72.     outp(basereg, c);
  73.     }
  74.  
  75. int follow;
  76.  
  77. int rcharto(ticks)
  78.     int ticks;
  79.     {
  80.     long tstamp, tstamp1, dayofticksp;
  81.     int c;
  82.     _bios_timeofday(_TIME_GETCLOCK, &tstamp);
  83.     dayofticksp=0;
  84.     while(1)
  85.         {
  86.         if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
  87.             dayofticksp+=20*60*60*24;
  88.         if(tstamp1+dayofticksp-tstamp>ticks)
  89.             return(-1); /* NOTE: This is an INT!!! */
  90.         if(follow!=index)
  91.             {
  92.             c=buf[follow++];
  93.             follow=follow%TBUFSIZ;
  94.             return(c);
  95.             }
  96.         }
  97.     }
  98.  
  99. int calccrc(ptr, count)
  100.     char *ptr;
  101.     int count;
  102.     {
  103.     int crc, i;
  104.     crc = 0;
  105.     while(--count >= 0)
  106.         {
  107.         crc = crc ^ (int)*ptr++ << 8;
  108.         for(i = 0; i < 8; ++i)
  109.             if(crc & 0x8000)
  110.                 crc = crc << 1 ^ 0x1021;
  111.             else
  112.                 crc = crc << 1;
  113.         }
  114.     return (crc & 0xFFFF);
  115.     }
  116.  
  117. unsigned char block[1024];
  118.  
  119. rblock(size)
  120. int size;
  121.     {
  122.     unsigned long crc;
  123.     unsigned long rcrc;
  124.     int c, i, j, blockn, invblockn;
  125.     crc=0;
  126.     if((blockn=rcharto(20))==-1)
  127.         return(-1);
  128.     printf("Block %d: ", blockn);
  129.     if((invblockn=rcharto(20))==-1)
  130.         return(-1);
  131.     for(i=0;i<size;++i)
  132.         if((c=rcharto(20))==-1)
  133.             return(-1);
  134.         else
  135.             block[i]=c;
  136.     if((c=rcharto(20))==-1)
  137.         return(-1);
  138.     rcrc=c<<8;
  139.     if((c=rcharto(20))==-1)
  140.         return(-1);
  141.     rcrc|=c;
  142.     crc=calccrc(block, size);
  143.     if(((invblockn^0xff)&0xff)!=blockn)
  144.         {
  145.         printf("Bad complement block number.\n");
  146.         return(-1);
  147.         }
  148.     if(crc!=rcrc)
  149.         {
  150.         printf("CRC mismatch. Here=%04x There=%04x\n", crc, rcrc);
  151.         return(-1);
  152.         }
  153.     return(blockn);
  154.     }
  155.  
  156. unsigned intnum;
  157. unsigned char oldintmask;
  158.  
  159. cleanup()
  160.     {
  161.     if(intnum==10)
  162.         outp(INTMASK2, oldintmask);
  163.     else
  164.         outp(INTMASK1, oldintmask);
  165.     outp(basereg+INTCTLREG, 0x00);
  166.     outp(basereg+MCTLREG, 0x03);
  167.     _dos_setvect(intnum, oldvect);
  168.     }
  169.  
  170. quit()
  171.     {
  172.     cleanup();
  173.     exit(99);
  174.     }
  175.  
  176. main(argc, argv)
  177.     int argc;
  178.     char **argv;
  179.     {
  180.     int i, j, outfd, ok, c;
  181.     unsigned char newintmask, lctl, dlmsb, dllsb, blocknum;
  182.     long nbytes;
  183.     unsigned speed;
  184.     int comnum, bsize;
  185.     char stopbits;
  186.     index=follow=0;
  187.     lctl=0;
  188.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  189.     printf("xmodem crc 1k receive of %s.\n", argv[4]);
  190.     if(argc!=5)
  191.         {
  192.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  193.         exit(1);
  194.         }
  195.     if((outfd=open(argv[4], O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, S_IWRITE))==-1)
  196.         {
  197.         printf("Error opening file %s.\n", argv[4]);
  198.         exit(2);
  199.         }
  200.     comnum=atoi(argv[1])-1;
  201.     newintmask=0;
  202.     switch(comnum)
  203.         {
  204.         case 0:
  205.             irqnum=4;
  206.             diffintmask=0xff&~0x10;
  207.             basereg=0x3f8;
  208.             break;
  209.         case 1:
  210.             irqnum=3;
  211.             diffintmask=0xff&~0x08;
  212.             basereg=0x2f8;
  213.             break;
  214.         case 2:
  215.             irqnum=4;
  216.             diffintmask=0xff&~0x10;
  217.             basereg=0x3e8;
  218.             break;
  219.         case 3:
  220.             irqnum=3;
  221.             diffintmask=0xff&~0x08;
  222.             basereg=0x2e8;
  223.             break;
  224.         case 4:
  225.             irqnum=2;
  226.             diffintmask=0xff&~0x02;
  227.             basereg=0x3e8;
  228.             break;
  229.         case 5:
  230.             irqnum=2;
  231.             diffintmask=0xff&~0x02;
  232.             basereg=0x2e8;
  233.             break;
  234.         case 6:
  235.             irqnum=5;
  236.             diffintmask=0xff&~0x20;
  237.             basereg=0x3e8;
  238.             break;
  239.         case 7:
  240.             irqnum=5;
  241.             diffintmask=0xff&~0x20;
  242.             basereg=0x2e8;
  243.             break;
  244.         default:
  245.             printf("Bad port choice.\n");
  246.             exit(4);
  247.         }
  248.     intnum=irqnum+8;
  249.     speed=atoi(argv[2]);
  250.     switch(speed)
  251.         {
  252.         case 300:
  253.             dlmsb=0;
  254.             dllsb=0xc0;
  255.             break;
  256.         case 1200:
  257.             dlmsb=0;
  258.             dllsb=0x60;
  259.             break;
  260.         case 2400:
  261.             dlmsb=0;
  262.             dllsb=0x30;
  263.             break;
  264.         case 9600:
  265.             dlmsb=0;
  266.             dllsb=0x0c;
  267.             break;
  268.         case 19200:
  269.             dlmsb=0;
  270.             dllsb=0x06;
  271.             break;
  272.         case 38400:
  273.             dlmsb=0;
  274.             dllsb=0x03;
  275.             break;
  276.         case 57600:
  277.             dlmsb=0;
  278.             dllsb=0x02;
  279.             break;
  280.         default:
  281.             printf("Bad speed.\n");
  282.             exit(5);
  283.         }
  284.     lctl|=DB8;
  285.     stopbits=argv[3][0];
  286.     switch(stopbits)
  287.         {
  288.         case '1':
  289.             break;
  290.         case '2':
  291.             lctl|=STOP2;
  292.             break;
  293.         default:
  294.             printf("Bad stop bits.\n");
  295.             exit(9);
  296.         }
  297.     signal(SIGINT, quit);
  298.     outp(basereg+LCTLREG, DLAB);
  299.     outp(basereg+DLLSBREG, dllsb);
  300.     outp(basereg+DLMSBREG, dlmsb);
  301.     outp(basereg+LCTLREG, lctl);
  302.     oldvect=_dos_getvect(intnum);
  303.     _dos_setvect(intnum, inthndl);
  304.     outp(basereg+INTCTLREG, 0x00);
  305.     outp(basereg+MCTLREG, 0x0b);
  306.     oldintmask=(intnum==10)?inp(INTMASK2):inp(INTMASK1);
  307.     newintmask=diffintmask;
  308.     newintmask&=oldintmask;
  309.     if(intnum==10)
  310.         outp(INTMASK2, newintmask);
  311.     else
  312.         outp(INTMASK1, newintmask);
  313.     outp(INTBASE1, INTACK);
  314.     outp(INTBASE2, INTACK);
  315.     outp(basereg+INTCTLREG, 0x01);
  316.     outp(INTBASE1, INTACK);
  317.     outp(INTBASE2, INTACK);
  318.     ok=nbytes=0;
  319.     for(i=0;i<10;++i)
  320.         {
  321.         sendchar('C');
  322.         c=rcharto(200);
  323.         if(c==SOH)
  324.             {
  325.             bsize=128;
  326.             ok=1;
  327.             break;
  328.             }
  329.         else if(c==STX)
  330.             {
  331.             bsize=1024;
  332.             ok=1;
  333.             break;
  334.             }
  335.         }
  336.     if(!ok)
  337.         {
  338.         printf("No SOH or STX after 10 10-second-spaced Cs.\n");
  339.         cleanup();
  340.         exit(10);
  341.         }
  342.     blocknum=1;
  343.     for(i=0;i<10;++i)
  344.         {
  345.         printf("\nSeeking block %d: ", blocknum);
  346.         if((c=rblock(bsize))==blocknum)
  347.             {
  348.             i=0;
  349.             if(write(outfd, block, bsize)!=bsize)
  350.                 {
  351.                 printf("Write error.\n");
  352.                 cleanup();
  353.                 exit(13);
  354.                 }
  355.             nbytes+=bsize;
  356.             printf("Successful. Bytes so far: %ld", nbytes);
  357.             blocknum=(blocknum+1)&0xff;
  358.             sendchar(ACK);
  359.             }
  360.         else if(c==-1)
  361.             {
  362.             while(rcharto(20)!=-1);
  363.             sendchar(NAK);
  364.             }
  365.         else if(c<blocknum)
  366.             sendchar(ACK);
  367.         else
  368.             {
  369.             printf("\nSender skipped a block; cancelling transfer.\n");
  370.             for(j=0;j<10;++j)
  371.                 sendchar(CAN);
  372.             cleanup();
  373.             exit(14);
  374.             }
  375.         do
  376.             c=rcharto(200);
  377.         while((c!=SOH)&&(c!=STX)&&(c!=EOT)&&(c!=CAN)&&(c!=-1));
  378.         if(c==EOT)
  379.             {
  380.             sendchar(ACK);
  381.             printf("\nTransfer successful.\n");
  382.             close(outfd);
  383.             cleanup();
  384.             exit(0);
  385.             }
  386.         if(c==SOH)
  387.             bsize=128;
  388.         else if(c==STX)
  389.             bsize=1024;
  390.         else
  391.             {
  392.             if(c==-1)
  393.                 printf("Timeout waiting for SOH or EOT.\n");
  394.             else
  395.                 printf("Spurrious character hex %02x; SOH or EOT expected.\n", c);
  396.             cleanup();
  397.             exit(11);
  398.             }
  399.         }
  400.     printf("Retry limit exceeded.\n");
  401.     cleanup();
  402.     exit(12);
  403.     }
  404.